1. Field of the Invention
The present invention relates generally to microprocessors, and more specifically to a RISC microprocessor having plural, symmetrical sets of registers.
2. Background
In addition to the usual complement of main memory storage and secondary permanent storage, a microprocessor-based computer system typically also includes one or more general purpose data registers, one or more address registers, and one or more status flags. Previous systems have included integer registers for holding integer data and floating point registers for holding floating point data. Typically, the status flags are used for indicating certain conditions resulting from the most recently executed operation. There generally are status flags for indicating whether, in the previous operation: a carry occurred, a negative number resulted, and/or a zero resulted.
These flags prove useful in determining the outcome of conditional branching within the flow of program control. For example, if it is desired to compare a first number to a second number and upon the conditions that the two are equal, to branch to a given subroutine, the microprocessor may compare the two numbers by subtracting one from the other, and setting or clearing the appropriate condition flags. The numerical value of the result of the subtraction need not be stored. A conditional branch instruction may then be executed, conditioned upon the status of the zero flag. While being simple to implement, this scheme lacks flexibility and power. Once the comparison has been performed, no further numerical or other operations may be performed before the conditional branch upon the appropriate flag; otherwise, the intervening instructions will overwrite the condition flag values resulting from the comparison, likely causing erroneous branching. The scheme is further complicated by the fact that it may be desirable to form greatly complex tests for branching, rather than the simple equality example given above.
For example, assume that the program should branch to the subroutine only upon the condition that a first number is greater than a second number, and a third number is less than a fourth number, and a fifth number is equal to a sixth number. It would be necessary for previous microprocessors to perform a lengthy series of comparisons heavily interspersed with conditional branches. A particularly undesirable feature of this serial scheme of comparing and branching is observed in any microprocessor having an instruction pipeline.
In a pipelined microprocessor, more than one instruction is being executed at any given time, with the plural instructions being in different stages of execution at any given moment. This provides for vastly improved throughput. A typical pipeline microprocessor may include pipeline stages for: (a) fetching an instruction, (b) decoding the instruction, (c) obtaining the instruction's operands, (d) executing the instruction, and (e) storing the results. The problem arises when a conditional branch instruction is fetched. It may be the case that the conditional branch's condition cannot yet be tested, as the operands may not yet be calculated, if they are to result from operations which are yet in the pipeline. This results in a “pipeline stall,” which dramatically slows down the processor.
Another shortcoming of previous microprocessor-based systems is that they have included only a single set of registers of any given data type. In previous architectures, when an increased number of registers has been desired within a given data type, the solution has been simply to increase the size of the single set of those type of registers. This may result in addressing problems, access conflict problems, and symmetry problems.
On a similar note, previous architectures have restricted each given register set to one respective numerical data type. Various prior systems have allowed general purpose registers to hold either numerical data or address “data,” but the present application will not use the term “data” to include addresses. What is intended may be best understood with reference to two prior systems. The Intel 8085 microprocessor includes a register pair “HL” which can be used to hold either two bytes of numerical data or one two-byte address. The present application's improvement is not directed to that issue. More on point, the Intel 80486 microprocessor includes a set of general purpose integer data registers and a set of floating point registers, with each set being limited to its respective data type, at least for purposes of direct register usage by arithmetic and logic units.
This proves wasteful of the microprocessor's resources, such as the available silicon area, when the microprocessor is performing operations which do not involve both data types. For example, user applications frequently involve exclusively integer operations, and perform no floating point operations whatsoever. When such a user application is run on a previous microprocessor which includes floating point registers (such as the 80486), those floating point registers remain idle during the entire execution.
Another problem with previous microprocessor register set architecture is observed in context switching or state switching between a user application and a higher access privilege level entity such as the operating system kernel. When control within the microprocessor switches context, mode, or state, the operating system kernel or other entity to which control is passed typically does not operate on the same data which the user application has been operating on. Thus, the data registers typically hold data values which are not useful to the new control entity but which must be maintained until the user application is resumed. The kernel must generally have registers for its own use, but typically has no way of knowing which registers are presently in use by the user application. In order to make space for its own data, the kernel must swap out or otherwise store the contents of a predetermined subset of the registers. This results in considerable loss of processing time to overhead, especially if the kernel makes repeated, short-duration assertions of control.
On a related note, in prior microprocessors, when it is required that a “grand scale” context switch be made, it has been necessary for the microprocessor to expend even greater amounts of processing resources, including a generally large number of processing cycles, to save all data and state information before making the switch. When context is switched back, the same performance penalty has previously been paid, to restore the system to its former state. For example, if a microprocessor is executing two user applications, each of which requires the full complement of registers of each data type, and each of which may be in various stages of condition code setting operations or numerical calculations, each switch from one user application to the other necessarily involves swapping or otherwise saving the contents of every data register and state flag in the system. This obviously involves a great deal of operational overhead, resulting in significant performance degradation, particularly if the main or the secondary storage to which the registers must be saved is significantly slower than the microprocessor itself.
Therefore, we have discovered that it is desirable to have an improved microprocessor architecture which allows the various component conditions of a complex condition to be calculated without any intervening conditional branches. We have further discovered that it is desirable that the plural simple conditions be calculable in parallel, to improve throughput of the microprocessor.
We have also discovered that it is desirable to have an architecture which allows multiple register sets within a given data type.
Additionally, we have discovered it to be desirable for a microprocessor's floating point registers to be usable as integer registers, in case the available integer registers are inadequate to optimally to hold the necessary amount of integer data. Notably, we have discovered that it is desirable that such re-typing be completely transparent to the user application.
We have discovered it to be highly desirable to have a microprocessor which provides a dedicated subset of registers which are reserved for use by the kernel in lieu of at least a subset of the user registers, and that this new set of registers should be addressable in exactly the same manner as the register subset which they replace, in order that the kernel may use the same register addressing scheme as user applications. We have further observed that it is desirable that the switch between the two subsets of registers require no microprocessor overhead cycles, in order to maximally utilize the microprocessor's resources.
Also, we have discovered it to be desirable to have a microprocessor architecture which allows for a “grand scale” context switch to be performed with minimal overhead. In this vein, we have discovered that is desirable to have an architecture which allows for plural banks of register sets of each type, such that two or more user applications may be operating in a multi-tasking environment, or other “simultaneous” mode, with each user application having sole access to at least a full bank of registers. It is our discovery that the register addressing scheme should, desirably, not differ between user applications, nor between register banks, to maximize simplicity of the user applications, and that the system should provide hardware support for switching between the register banks so that the user applications need not be aware of which register bank which they are presently using or even of the existence of other register banks or of other user applications.
These and other advantages of our invention will be appreciated with reference to the following description of our invention, the accompanying drawings, and the claims.